package com.fpost.action;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.LookupDispatchAction;

import com.fpost.constants.ActionConstants;
import com.fpost.domain.Article;
import com.fpost.form.ArticleSearchForm;
import com.fpost.form.dto.ArticleDTO;
import com.fpost.form.dto.UserDTO;
import com.fpost.manager.ArticleManager;
import com.fpost.manager.SearchManager;
import com.fpost.security.ActionSecurityUtils;
import com.fpost.util.CommonUtils;
import com.fpost.util.FpostCache;

public class ArticleSearchAction extends LookupDispatchAction {
	
	private static Logger log = Logger.getLogger(ArticleSearchAction.class);

	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		//set current path in session
		CommonUtils.setCurrentPathInSession(request, mapping);
		
		String method = request.getParameter("method");		
		if (method == null){
			return unspecified(mapping, form, request, response);
		} 
		return super.execute(mapping, form, request, response);
	}
	
	protected Map<String, String> getKeyMethodMap() {
		
		Map<String, String> map = new HashMap<String, String>();		
		map.put("articleSearchForm.author", "author");		
		map.put("articleSearchForm.search", "search");	
		map.put("articleSearchForm.login", "login");
		map.put("articleSearchForm.logout", "logout");
		return map;		
	}
	
	public ActionForward author(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		ResourceBundle resourceBundle = CommonUtils.getResourceBundle(request);

		String forward = ActionConstants.SUCCESS;
		ArticleSearchForm articleSearchForm = (ArticleSearchForm) form;	
		
		try {					
			articleSearchForm.setArticleTypeDTOList(FpostCache.getInstance().getArticleTypeDTOList());
			articleSearchForm.setMessage1("");
			articleSearchForm.setMessage2("");
			
			List<Article> articles = new ArrayList<Article>();
			ArticleManager articleManager = new ArticleManager();
			
			//String username = UnicodeConverter.convertToUnicode(request.getParameter(CommonConstants.USERNAME));
			//System.out.println(username);
			
			UserDTO userDTO = ActionSecurityUtils.getUserDTO_fromSession(request);
			if (userDTO == null) {
				forward  = ActionConstants.LOGIN;
			} else {	
				long userId = Long.parseLong(userDTO.getUserId());
				
				long count = 0;
				double startTime = System.currentTimeMillis();				
				double countTime = 0;
				
				count = articleManager.countCurrentArticlesByUserId_HQL(userId);
				countTime = System.currentTimeMillis() - startTime;
		    	startTime = System.currentTimeMillis();
				
		    	if (count > ActionConstants.MAX_SEARCH_RESULTS) {
					articleSearchForm.setMessage1(resourceBundle.getString("articleSearch.message1"));
				} else if (count != 0) {
					articles = articleManager.getCurrentArticlesByUserId(userId);
				}

				double searchTime = System.currentTimeMillis() - startTime;				
				MessageFormat mf = new MessageFormat(resourceBundle.getString("articleSearch.message2"));
				articleSearchForm.setMessage2(mf.format(
						new Object[] {count, (countTime + searchTime)/1000, countTime/1000, searchTime/1000}));
								
				List<ArticleDTO> articleDTOList = new ArrayList<ArticleDTO>();			
				for (Article article : articles) {			
					articleDTOList.add(new ArticleDTO(article, true));
				}			
				articleSearchForm.setArticleDTOList(articleDTOList);				
			} 
		} catch (NumberFormatException e) {
			log.error(e.getMessage());
			forward = ActionConstants.FAILURE;			
		} catch (Exception e) {			
			log.error(e.getMessage());
			forward  = ActionConstants.SYSTEM_FAILURE;
		}
		return mapping.findForward(forward);
	}
	
	public ActionForward search(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		ResourceBundle resourceBundle = CommonUtils.getResourceBundle(request);
		
		String forward = ActionConstants.SUCCESS;		
		try {
			ArticleSearchForm articleSearchForm = (ArticleSearchForm) form;			
			articleSearchForm.setArticleTypeDTOList(FpostCache.getInstance().getArticleTypeDTOList());
			articleSearchForm.setMessage1("");
			articleSearchForm.setMessage2("");
			
			List<Article> articles = new ArrayList<Article>();
			SearchManager searchManager = new SearchManager();

			String input = articleSearchForm.getInput();
			
			long count = 0;
			List<Long> articleIds = null;
			double startTime = System.currentTimeMillis();
			double countTime = 0;
			
			//common search 			
		    if (input != null && !"".equals(input.trim())) {
		    	long articleTypeId = Long.parseLong(articleSearchForm.getArticleTypeId());
		    	
		    	articleIds = searchManager.fastGetCurrentArticleIdsByInputAndType(input.trim(), articleTypeId);
		    	count = articleIds.size();
		    	//count = searchManager.fastCountCurrentArticlesByInputAndType(input.trim(), articleTypeId);		    	
		    	
		    	countTime = System.currentTimeMillis() - startTime;
		    	startTime = System.currentTimeMillis();
		    	
		    	if (count > ActionConstants.MAX_SEARCH_RESULTS) {
					articleSearchForm.setMessage1(resourceBundle.getString("articleSearch.message1"));					
		    	} else if (count > 0){
		    		articles = new ArticleManager().getCurrentArticlesByArticleIds(articleIds);
		    		//articles = searchManager.fastGetCurrentArticlesByInputAndType(input.trim(), articleTypeId);
		    	}
			}
		    
		    double searchTime = System.currentTimeMillis() - startTime;
		    MessageFormat mf = new MessageFormat(resourceBundle.getString("articleSearch.message2"));
			articleSearchForm.setMessage2(mf.format(
					new Object[] {count, (countTime + searchTime)/1000, countTime/1000, searchTime/1000}));
			
			List<ArticleDTO> articleDTOList = new ArrayList<ArticleDTO>();			
			for (Article article : articles) {			
				articleDTOList.add(new ArticleDTO(article, true));
			}			
			articleSearchForm.setArticleDTOList(articleDTOList);
		} catch (Exception e) {
			log.error(e.getMessage());
			forward  = ActionConstants.SYSTEM_FAILURE;
		}
		
		return mapping.findForward(forward);
	}
	
	public ActionForward unspecified(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		ArticleSearchForm articleSearchForm = (ArticleSearchForm) form;			
		articleSearchForm.setArticleTypeDTOList(FpostCache.getInstance().getArticleTypeDTOList());
		articleSearchForm.setArticleDTOList(new ArrayList<ArticleDTO>());
		return mapping.findForward(ActionConstants.SUCCESS);
	}
	
	public ActionForward login(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return unspecified(mapping, form, request, response);
	}
	
	public ActionForward logout(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return unspecified(mapping, form, request, response);
	}

}
